<?php

namespace app\service;

use app\exception\ErrnoPlus;
use app\model\DeviceGroupTableModel;
use app\service\cache\DeviceGroupTableCacheService;
use share\exception\ApiException;
use share\service\BaseModelService;
use share\utils\Helper;

class DeviceGroupTableService extends BaseModelService
{
    /**
     * 用户最多添加分组数量
     */
    const USER_SET_GROUP_MAX_NUM = 32;

    public static function getModel()
    {
        return new DeviceGroupTableModel;
    }

    public static function getAllByUser($uid)
    {
        return self::getAllByFilter(['uid' => $uid]);
    }


    public static function deleteByUser($uid)
    {
        DeviceGroupTableCacheService::del(['uid'=> $uid]);   
        return DeviceGroupTableModel::destroy(['uid' => $uid]);
    }

    public static function deleteByUserMainIds($uid, $mainIds)
    {
        $mainIdInfos = DeviceGroupTableCacheService::getAllByFilter([
            'uid' => $uid,
            'main_id' =>[ 'in', $mainIds],
        ]);
        $uids = array_column($mainIdInfos,'uid');
        array_push($uids,$uid);
        $uids = Helper::arraySmartUnique($uids);
        // 用户删除绑定  
        DeviceGroupTableCacheService::delAllByUserIds($uids);
        return DeviceGroupTableModel::destroy(['uid' => $uid, 'main_id' =>[ 'in', $mainIds]]);
    }


    public static function getListGroupInfo($param,$uid){   
        $filter = [
            "uid" => $uid,
            "vendor" => $param['vendor']
        ];
        if (isset($param['groupIds']) && count($param['groupIds']) > 0) {
            $filter["group_id"] = ["in", $param['groupIds']];
        }
        $res = DeviceGroupTableCacheService::getAllByFilter($filter);
        if(empty($res)){
            return null;
        }
        $result = [];
        foreach ($res as $vo) {
            $groupId = $vo['group_id'];
            $tmp = [
                "channel" => $vo['group_chan'],
                "mainId" => $vo['main_id'],
                "subId" => $vo['sub_id'],
                "owned" => $vo['owned'],
                "deviceChannel" => $vo['device_chan'],
                "deviceName" => $vo['device_name']
            ];
            if(!isset($result[$groupId])){
                $result[$groupId] = [
                    "groupId" => $groupId,
                    "groupName" => $vo['group_name'],
                    "deviceList" => [
                        $tmp
                    ]
                ];
            }
            else{
                $result[$groupId]['deviceList'][] = $tmp;
            }           
        }
        return array_values($result);
    }

    public static function addGroupInfo($param,$uid,$groupId = ''){
   
        $count = DeviceGroupTableModel::where("uid", $uid)->count("distinct group_id");
        if($count >= self::USER_SET_GROUP_MAX_NUM){
            throw new ApiException("your  device group is more than ".self::USER_SET_GROUP_MAX_NUM.'!',ErrnoPlus::GROUP_DEVICE_COUNT);
        }
        if(empty($groupId)){
            $groupId = Helper::getUnique();
        }
     
        $shareDevice = UserDeviceShareService::getAllByShareUser($uid);
        $addData = [];
        $tn = time();
        foreach ($param["deviceList"] as $deviceList) {
            if($deviceList['owned'] === 0){
                $tmp = Helper::filterOne($shareDevice,['main_id' => $deviceList['mainId']]);
                if(empty($tmp)){
                    throw new ApiException("the device ".$deviceList['mainId']." is not shared to you",ErrnoPlus::SHARE_NOT_EXISTS);
                }
            }
            $addData[] = [
                'uid' => $uid,
                'vendor' => $param['vendor'],
                "group_name" => $param["groupName"],
                'group_id' => $groupId,
                'sub_id' => $deviceList["subId"],
                'group_chan' => $deviceList["channel"],
                'main_id' => $deviceList["mainId"],
                'owned' => $deviceList["owned"],
                'device_chan' => $deviceList["deviceChannel"],
                'device_name' => $deviceList["deviceName"],
                'first_time' => $tn,
                'modify_time' => $tn,
            ];
        }
        self::addBulk($addData);
        DeviceGroupTableCacheService::del(['uid'=>$uid]);
    }

    public static function updateGroupInfo($groupId,$param,$uid){
        $allExist = self::getAllByFilter(['group_id' => $groupId,'uid' => $uid]);
        if(!$allExist){
            unset($param['groupId']);
            return self::addGroupInfo($param,$uid,$groupId);
        }
       
        $shareDevice = UserDeviceShareService::getAllByShareUser($uid);
        $addData = [];
        $updateData = [];
        $tn = time();
        $subIds = [];
        foreach ($param["deviceList"] as $deviceList) {
            $item = [
                'uid' => $uid,
                'vendor' => $param['vendor'],
                "group_name" => $param["groupName"],
                'group_id' => $groupId,
                'sub_id' => $deviceList["subId"],
                'group_chan' => $deviceList["channel"],
                'main_id' => $deviceList["mainId"],
                'owned' => $deviceList["owned"],
                'device_chan' => $deviceList["deviceChannel"],
                'device_name' => $deviceList["deviceName"],
            ];
            $subIds[] =$deviceList["subId"];
            if($deviceList["owned"] === 0){
                $tmp = Helper::filterOne($shareDevice,['main_id' => $deviceList['mainId']]);
                if(empty($tmp)){
                    throw new ApiException("the device ".$deviceList['mainId']." is not shared to you",ErrnoPlus::SHARE_NOT_EXISTS);
                }
            }
            $origin = Helper::filterOne($allExist,['sub_id' => $deviceList['subId']]);
            if(empty($origin)){
                $item['first_time'] = $tn;
                $item['modify_time'] = $tn;
                $addData[] = $item;
            }
            else{
                $updateField = [];
                foreach(array_keys($item) as $key){
                    if($item[$key] !== $origin[$key]){
                        $updateField[$key] = $item[$key];
                    }
                }
                if(count($updateField) > 0){
                    $updateField['modify_time'] = $tn;
                    $updateData[$origin['id']] = $updateField;
                }
            }
        }
        // 需要 删除的
        $existSubIds = Helper::arraySmartUnique(array_column($allExist,'sub_id'));
        $delSubIds = array_diff($existSubIds,$subIds);
        if(count($delSubIds)){
            self::delByFilter([
                'group_id' => $groupId,
                'uid' => $uid,
                'sub_id' => ['in', $delSubIds],
            ]);
        }
        // 需要更新的
        if(count($updateData) > 0){
            foreach($updateData as $key => $data){
                self::update($key,$data);
            }
        }
        // 需要添加的
        if(count($addData) > 0){
            DeviceGroupTableModel::insertAll($addData);
        }
        // 更新缓存
        DeviceGroupTableCacheService::del(['uid'=>$uid]);
    }

    public static function delGroupInfo($param,$uid){
        $filter = [
            "uid" => $uid,
            "vendor" => $param['vendor']
        ];
        if (isset($param['groupIds']) && count($param['groupIds']) > 0) {
            $filter["group_id"] = ["in", $param['groupIds']];
        }
        self::delByFilter($filter);
        DeviceGroupTableCacheService::del($filter);
    }
}
